import { ref, computed } from 'vue';

export default function useTree(nodeKey: string, titleKey: string, dropCallback: any) {
  const selfKey = nodeKey || 'key';
  const selfTitleKey = titleKey || 'title';

  const search = ref('');

  const originTreeData = ref<any[]>([]);

  const searchData = (keyword: string) => {
    const loop = (data: any) => {
      const result: any[] = [];
      data.forEach((item: any) => {
        if (item[selfTitleKey].toLowerCase().indexOf(keyword.toLowerCase()) > -1) {
          result.push({ ...item });
        } else if (item.children) {
          const filterData = loop(item.children);
          if (filterData.length) {
            result.push({
              ...item,
              children: filterData,
            });
          }
        }
      });
      return result;
    };

    return loop(originTreeData.value);
  };

  const treeData = computed(() => {
    if (!search.value) return originTreeData.value;
    return searchData(search.value);
  });

  const setTreeData = (value: any[]) => {
    originTreeData.value = value;
  };

  // @ts-ignore
  const onDrop = ({ dragNode, dropNode, dropPosition }) => {
    const data = originTreeData.value;

    const loop = (loopData: any[], key: string, callback: any) => {
      loopData.some((item, index, arr) => {
        if (item[selfKey] === key) {
          callback(item, index, arr);
          return true;
        }
        if (item.children) {
          return loop(item.children, key, callback);
        }
        return false;
      });
    };

    loop(data, dragNode[selfKey], (_: any, index: number, arr: any[]) => {
      arr.splice(index, 1);
    });

    if (dropPosition === 0) {
      loop(data, dropNode[selfKey], (item: any) => {
        item.children = item.children || [];
        item.children.push(dragNode);
      });
    } else {
      loop(data, dropNode[selfKey], (_: any, index: number, arr: any[]) => {
        arr.splice(dropPosition < 0 ? index : index + 1, 0, dragNode);
      });
    }
    if (dropCallback) {
      dropCallback(originTreeData.value);
    }
  };

  return {
    search,
    treeData,
    setTreeData,
    onDrop,
  };
}
